package com.vegetable.modules.service.quotation.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vegetable.common.utils.Constant;
import com.vegetable.modules.entity.baseData.ProductSpec;
import com.vegetable.modules.entity.baseData.Products;
import com.vegetable.modules.entity.quotation.Quotation;
import com.vegetable.modules.entity.quotation.QuotationArea;
import com.vegetable.modules.entity.quotation.QuotationLog;
import com.vegetable.modules.entity.quotation.po.QuotationPO;
import com.vegetable.modules.entity.quotation.po.QuotationQueryPO;
import com.vegetable.modules.mapper.quotation.QuotationMapper;
import com.vegetable.modules.service.baseData.IProductSpecService;
import com.vegetable.modules.service.baseData.IProductsService;
import com.vegetable.modules.service.quotation.IQuotationAreaService;
import com.vegetable.modules.service.quotation.IQuotationLogService;
import com.vegetable.modules.service.quotation.IQuotationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
//@AllArgsConstructor
public class IQuotationServiceImpl extends ServiceImpl<QuotationMapper, Quotation>  implements IQuotationService {
    @Resource
    private IProductsService iProductsService;
    @Resource
    private IProductSpecService iProductSpecService;
    @Resource
    private IQuotationLogService iQuotationLogService;
    @Resource
    private IQuotationAreaService iQuotationAreaService;
    @Override
    public List<Quotation> quotationList(QuotationQueryPO param) {
        QueryWrapper<Quotation> logQuery = new QueryWrapper<Quotation>()
                .eq(ObjectUtils.isNotEmpty(param.getAreaId()),"area_id", param.getAreaId())
                .eq(ObjectUtils.isNotEmpty(param.getProductType()),"product_type", param.getProductType())
                .like(ObjectUtils.isNotEmpty(param.getProductNameLike()),"product_name", param.getProductNameLike());
        if(ObjectUtils.isNotNull(param.getUpdateTime())){
            logQuery.between("update_time", DateUtil.beginOfDay(param.getUpdateTime()), DateUtil.endOfDay(param.getUpdateTime()));
        }

        // 前端传入的排序字段
        String orderBy = param.getOrderBy();
        if(ObjectUtils.isNull(orderBy)){
            // 如果没有排序字段则按照更新时间倒序
            logQuery.orderByDesc( "product_type", "product_name", "update_time");
        }else if(Constant.ASC.equalsIgnoreCase(param.getSort())){
            logQuery.orderByAsc(orderBy);
        }else{
            logQuery.orderByDesc(orderBy);
        }
        return this.baseMapper.selectList(logQuery);
    }

    @Override
    public int reloadQuotation() {
        QueryWrapper<Products> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tags", 2);
        queryWrapper.eq("is_enabled", 0);
        List<Products> productsList = iProductsService.list(queryWrapper);
        for(Products product : productsList){
            Long productId = product.getId();
            String s = "";
            if(NumberUtil.isGreaterOrEqual(product.getStandardWeight(), BigDecimal.ZERO)){
                s = "(" + product.getStandardWeight() + "公斤)";
                s = s.replace(".00", "");
            }
            List<ProductSpec> specList = iProductSpecService.queryByProductId(productId);
            if(CollectionUtil.isNotEmpty(specList)){
                for(ProductSpec spec : specList){
                    Quotation quotation = queryByCommodityIdAndSpecsId(productId, spec.getId());
                    if(ObjectUtil.isNull(quotation)){
                        QuotationArea area = iQuotationAreaService.quotationArea(product.getPlaceOrigin());
                        Quotation saver = new Quotation();
                        saver.setProductType(product.getCategory());
                        saver.setProductName(product.getCommonName() + s +" -- " + spec.getName());
                        saver.setAreaId(ObjectUtil.isNull(area) ? 0L : area.getId());
                        saver.setCommodityId(product.getId());
                        saver.setSpecsId(spec.getId());
                        this.baseMapper.insert(saver);
                    }
                }
            }else {
                QuotationArea area = iQuotationAreaService.quotationArea(product.getPlaceOrigin());
                Quotation saver = new Quotation();
                saver.setProductType(product.getCategory());
                saver.setProductName(product.getCommonName() + s);
                saver.setAreaId(ObjectUtil.isNull(area) ? 0L : area.getId());
                saver.setCommodityId(product.getId());
                this.baseMapper.insert(saver);
            }
        }
        return 0;
    }

    @Override
    public Quotation queryByCommodityIdAndSpecsId(Long commodityId, Long specsId) {
        QueryWrapper<Quotation> wrapper = new QueryWrapper<>();
        wrapper.eq("commodity_id", commodityId);
        if(ObjectUtil.isNull(specsId)){
            wrapper.isNull("specs_id");
        }else {
            wrapper.eq("specs_id", specsId);
        }
        return this.baseMapper.selectOne(wrapper);
    }

    @Override
    public Quotation queryByCommodityNameAndArea(String commodityName, Long areaId) {
        QueryWrapper<Quotation> wrapper = new QueryWrapper<>();
        wrapper.eq("product_name", commodityName);
        wrapper.eq("area_id", areaId);
        return this.baseMapper.selectOne(wrapper);
    }

    @Override
    public void saveQuotation(QuotationPO param) {
        Quotation quotation = new Quotation();
        BeanUtils.copyProperties(param, quotation);
        // 1. 保存报价单
        save(quotation);
        // 2. 保存报价单日志
        saveLog(param, new Date());
        log.info("新增报价单 --> {}", JSON.toJSONString(param));
    }

    @Override
    public void updateQuotation(QuotationPO param) {
        Date updateTime = new Date();
        updateQuotation(param, updateTime);
    }

    public void updateQuotation(QuotationPO param, Date updateTime) {
        Quotation quotation = new Quotation();
        BeanUtils.copyProperties(param, quotation);
        quotation.setUpdateTime(updateTime);
        if(DateUtil.formatDate(updateTime).equals(DateUtil.formatDate(new Date()))){
            // 1. 保存报价单
            updateById(quotation);
        }
        // 2. 保存报价单日志
        saveLog(param, updateTime);
    }
    @Override
    public void updateQuotation(BigDecimal newPrice, Long quotationId, Date updateTime, BigDecimal numPrice) {
        Quotation quotation = baseMapper.selectById(quotationId);
        if(ObjectUtil.isNull(quotation)){
            log.info("根据{}没有找到报价信息，请仔细检查后重试", quotationId);
            return;
        }
        QuotationPO updater = new QuotationPO();
        updater.setId(quotationId);
        BigDecimal topPrice = quotation.getTopPrice();
        BigDecimal lowPrice = quotation.getLowPrice();
        if(!DateUtil.formatDate(quotation.getUpdateTime()).equals(DateUtil.formatDate(updateTime))){
            updater.setTopPrice(newPrice);
            updater.setLowPrice(newPrice);
        }else if(NumberUtil.equals(topPrice, BigDecimal.ZERO) || NumberUtil.equals(lowPrice, BigDecimal.ZERO)){
            updater.setTopPrice(newPrice);
            updater.setLowPrice(newPrice);
        } else if(NumberUtil.isGreater(newPrice, topPrice)){
            updater.setTopPrice(newPrice);
        } else if (NumberUtil.isLess(newPrice, lowPrice)) {
            updater.setLowPrice(newPrice);
//        }else {
//            updater.setId(null);
//            // 价格区间不变
        }
//        if(ObjectUtil.isNotNull(updater.getId())){
            updateQuotation(updater, updateTime);
//        }
    }

    @Override
    public QuotationLog queryQuotation(Long quotationId, Date queryDate) {
        QueryWrapper<QuotationLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("quotation_id", quotationId)
                .apply("DATE(create_time) = DATE({0})", queryDate)
                .orderByDesc("create_time", "id")
                .last("limit 1");
        return iQuotationLogService.getBaseMapper().selectOne(queryWrapper);
    }

    /**
     * 保存报价单更改日志
     * @param param
     */
    private void saveLog(QuotationPO param, Date orderTime) {
        QuotationLog qLog = new QuotationLog();
        qLog.setQuotationId(param.getId());
        qLog.setLowPrice(param.getLowPrice());
        qLog.setTopPrice(param.getTopPrice());
        qLog.setOrderTime(orderTime);
        iQuotationLogService.save(qLog);
    }
}
